package com.example.demo.shared;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.*;

@RestController
@RequestMapping("/articles")
public class ArticleController {

    private final RestHighLevelClient client;
    private final ObjectMapper objectMapper;

    @Autowired
    public ArticleController(RestHighLevelClient client, ObjectMapper objectMapper) {
        this.client = client;
        this.objectMapper = objectMapper;
    }

    /**
     * 放置标题索引
     * @param requestBody：directory是UUID名称，titles是标题字符串数组，可以放多个文档
     * @return 1成功0失败
     */
    @PostMapping("/indexTitles")
    public ResponseEntity<String> putTitles(@RequestBody Map<String, Object> requestBody) {
        String directory = (String) requestBody.get("directory");
        List<String> titles = (List<String>) requestBody.get("titles");
        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (String title : titles) {
                IndexRequest indexRequest = new IndexRequest(directory);
                indexRequest.id(UUID.randomUUID().toString());
                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("title", title);
                indexRequest.source(dataMap);
                bulkRequest.add(indexRequest);
            }
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
            return ResponseEntity.ok().body("Titles indexed successfully");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 放置作者索引
     * @param requestBody：directory是UUID名称，authors是作者字符串数组，可以放多个文档
     * @return 1成功0失败
     */
    @PostMapping("/indexAuthors")
    public ResponseEntity<String> putAuthors(@RequestBody Map<String, Object> requestBody) {
        String directory = (String) requestBody.get("directory");
        List<String> authors = (List<String>) requestBody.get("authors");
        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (String author : authors) {
                IndexRequest indexRequest = new IndexRequest(directory);
                indexRequest.id(UUID.randomUUID().toString());
                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("author", author);
                indexRequest.source(dataMap);
                bulkRequest.add(indexRequest);
            }
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
            return ResponseEntity.ok().body("Authors indexed successfully");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 放置关键词索引
     * @param requestBody：directory是UUID名称，keywords是关键词字符串数组，可以放多个文档
     * @return 1成功0失败
     */
    @PostMapping("/indexKeywords")
    public ResponseEntity<String> putKeywords(@RequestBody Map<String, Object> requestBody) {
        String directory = (String) requestBody.get("directory");
        List<String> keywords = (List<String>) requestBody.get("keywords");
        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (String keyword : keywords) {
                IndexRequest indexRequest = new IndexRequest(directory);
                indexRequest.id(UUID.randomUUID().toString());
                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("keyword", keyword);
                indexRequest.source(dataMap);
                bulkRequest.add(indexRequest);
            }
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
            return ResponseEntity.ok().body("Keywords indexed successfully");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 放置摘要索引
     * @param requestBody：directory是UUID名称，abstracts是摘要字符串数组，可以放多个文档
     * @return 1成功0失败
     */
    @PostMapping("/indexAbstracts")
    public ResponseEntity<String> putAbstracts(@RequestBody Map<String, Object> requestBody) {
        String directory = (String) requestBody.get("directory");
        List<String> abstracts = (List<String>) requestBody.get("abstracts");
        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (String abst : abstracts) {
                IndexRequest indexRequest = new IndexRequest(directory);
                indexRequest.id(UUID.randomUUID().toString());
                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("abstract", abst);
                indexRequest.source(dataMap);
                bulkRequest.add(indexRequest);
            }
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
            return ResponseEntity.ok().body("Abstracts indexed successfully");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 查找标题
     * @param requestBody：query是查找的字符串
     * @return 返回json格式
     */
    @GetMapping("/searchTitle")
    public ResponseEntity<Map<String, Object>> searchArticlesByTitle(@RequestParam String query) {
        try {
            SearchRequest searchRequest = new SearchRequest("articles");
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(QueryBuilders.matchQuery("title", query));
            searchSourceBuilder.highlighter(new HighlightBuilder().field("title"));
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

            SearchHits searchHits = searchResponse.getHits();
            Map<String, Object> response = new HashMap<>();
            response.put("totalHits", searchHits.getTotalHits());

            List<Map<String, Object>> hits = new ArrayList<>();
            for (SearchHit hit : searchHits) {
                Map<String, Object> hitData = new HashMap<>();
                hitData.put("title", hit.getSourceAsMap().get("title"));
                hitData.put("score", hit.getScore());

                Text[] fragments = hit.getHighlightFields().get("title").fragments();
                List<String> contexts = new ArrayList<>();
                for (Text fragment : fragments) {
                    contexts.add(fragment.toString());
                }
                hitData.put("contexts", contexts);

                hits.add(hitData);
            }
            response.put("hits", hits);
            return ResponseEntity.ok().body(response);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}
